package com.evil.account.mapper;

import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.evil.account.pojo.dto.enterprise.EnterpriseBaseInfoResp;
import com.evil.account.pojo.entity.Enterprise;
import com.evil.common.account.dto.enterprise.EnterpriseBaseRespDTO;
import com.evil.common.account.dto.enterprise.EnterprisePageReqDTO;
import com.evil.common.account.dto.enterprise.EnterprisePageRespDTO;
import com.evil.common.account.util.AccountRedisKeyUtil;
import com.evil.common.core.constant.RedisConstant;
import com.evil.common.core.entity.QueryModel;
import com.evil.common.core.enums.RCodeEnum;
import com.evil.common.core.enums.SwitchEnum;
import com.evil.common.core.exception.BusinessException;
import com.evil.common.core.util.CacheMapperUtil;
import com.evil.common.core.util.StreamUtil;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import org.apache.ibatis.annotations.Param;

import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Optional;

/**
 * 企业表
 *
 * @author liyang
 * @date 2022-08-08 00:00
 */
public interface EnterpriseMapper extends BaseMapper<Enterprise> {

    default Optional<Enterprise> isExistById(Long id) {
        return Optional.ofNullable(this.selectById(id));
    }

    default Optional<Enterprise> isExistById_Cache(Long id) {
        return CacheMapperUtil.cacheById(
                id,
                Enterprise.class,
                this::findById,
                AccountRedisKeyUtil::requestUuidEnterpriseKey,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    default Enterprise findById(Long id) {
        return this.isExistById(id).orElseThrow(() -> new BusinessException(RCodeEnum.ENTERPRISE_NOT_EXIST));
    }

    default Enterprise findById_Cache(Long id) {
        return this.isExistById(id).orElseThrow(() -> new BusinessException(RCodeEnum.ENTERPRISE_NOT_EXIST));
    }

    default Enterprise findNormalById(Long id) {
        return this.isExistById(id)
                .filter(d -> !SwitchEnum.isOpen(d.getIsDeleted()))
                .orElseThrow(() -> new BusinessException(RCodeEnum.ENTERPRISE_NOT_EXIST));
    }

    Optional<EnterpriseBaseRespDTO> findBaseById(@Param("id") Long id);

    Optional<EnterpriseBaseInfoResp> findBaseInfoById(Long id);

    List<Enterprise> findByIds(@Param("ids") Collection<Long> ids, @Param("filterDeleted") boolean filterDeleted);

    List<EnterpriseBaseRespDTO> findBaseByIds(@Param("ids") Collection<Long> ids, @Param("filterDeleted") boolean filterDeleted);

    List<Enterprise> findListByPlatformType(Integer platformType);

    default List<EnterpriseBaseRespDTO> findBaseByIds_Cache(Collection<Long> ids, boolean filterDeleted) {
        return CacheMapperUtil.cacheByIds(
                ids,
                filterDeleted,
                EnterpriseBaseRespDTO.class,
                this::findBaseByIds,
                EnterpriseBaseRespDTO::getEnterpriseId,
                u -> SwitchEnum.NO.getId(),
                null,
                AccountRedisKeyUtil::requestUuidEnterpriseBaseKeyMap,
                RedisConstant.REQUEST_UUID_EXPIRE_IN_SECOND
        );
    }

    default Map<Long, Enterprise> findMapByIds(Collection<Long> ids, boolean filterDeleted) {
        return StreamUtil.toMapK(this.findByIds(ids, filterDeleted), Enterprise::getEnterpriseId);
    }

    default Map<Long, EnterpriseBaseRespDTO> findBaseMapByIds(Collection<Long> ids, boolean filterDeleted) {
        return StreamUtil.toMapK(this.findBaseByIds(ids, filterDeleted), EnterpriseBaseRespDTO::getEnterpriseId);
    }

    List<EnterprisePageRespDTO> enterprises(EnterprisePageReqDTO enterprisePageReqDTO);

    default PageInfo<EnterprisePageRespDTO> enterprisePage(QueryModel<EnterprisePageReqDTO> queryModel) {
        return PageHelper.startPage(queryModel.getPageNum(), queryModel.getPageSize(), queryModel.initOrder())
                .doSelectPageInfo(() -> this.enterprises(queryModel.getParam()));
    }

    /**
     * 获取平台
     *
     * @return Optional
     */
    Optional<EnterpriseBaseInfoResp> platformEnterprise();
}